package br.org.acessobrasil.portal.action;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import br.org.acessobrasil.portal.controle.SecurityManager;
import br.org.acessobrasil.portal.modelo.Conteudo;
import br.org.acessobrasil.portal.modelo.ItemConteudo;
import br.org.acessobrasil.portal.modelo.Pagina;
import br.org.acessobrasil.portal.modelo.Sitio;
import br.org.acessobrasil.portal.modelo.TipoConteudo;
import br.org.acessobrasil.portal.modelo.Usuario;
import br.org.acessobrasil.portal.persistencia.ConteudoDaoSpring;
import br.org.acessobrasil.portal.persistencia.LogDao;
import br.org.acessobrasil.portal.persistencia.PaginaDaoSpring;
import br.org.acessobrasil.portal.persistencia.TipoConteudoDaoSpring;
import br.org.acessobrasil.portal.persistencia.UsuarioDaoSpring;
/**
 * Trata os conteudos, uma pagina possui n conteudos.<br>
 * Os conteudos possuem n itens
 * @author Fabio Issamu Oshiro
 *
 */
public class ConteudoAction extends Super {
	private static Logger logger = Logger.getLogger(ConteudoAction.class);
	private static final long serialVersionUID = 65420325306103444L;
	private List<Conteudo> listConteudo;
	public static ConteudoDaoSpring conteudoDao;
	public static PaginaDaoSpring paginaDao;
	public static UsuarioDaoSpring usuarioDao;
	public static TipoConteudoDaoSpring tipoConteudoDao;
	private Conteudo conteudo;
	private List<Pagina> listPagina;
	private List<TipoConteudo> listTipoConteudo;
	private Sitio sitio;
	private Pagina pagina;
	private LogDao logDao = LogDao.getInstance(); 
	private List<String> listaDeNomesDeArea = new ArrayList<String>();
	public ConteudoAction(ConteudoDaoSpring conteudoDao, PaginaDaoSpring paginaDao, TipoConteudoDaoSpring tipoConteudoDao, UsuarioDaoSpring usuarioDao) {
		ConteudoAction.conteudoDao = conteudoDao;
		ConteudoAction.paginaDao = paginaDao;
		ConteudoAction.tipoConteudoDao = tipoConteudoDao;
		ConteudoAction.usuarioDao = usuarioDao;
	}

	/**
	 * Carrega as listas necess&aacute;rias para montar a tela.<br>
	 * As listas s&atilde;o do sitioAtual.
	 */
	private void carregarListas() {
		Sitio sitio = getSitioAtual();
		listPagina = paginaDao.list(sitio.getNuSitio());
		listTipoConteudo = tipoConteudoDao.list(sitio);
	}

	/**
	 * Inicia o processo de incluir um conte&uacute;do
	 * @return sucesso
	 */
	public String preAdicionarConteudo() {
		Usuario usuario = getUsuarioLogado();
		carregarListas();
		if (conteudo==null || conteudo.getNuConteudo()==null){
			if(conteudo==null) conteudo = new Conteudo();
			if(conteudo.getNoConteudo()==null) conteudo.setNoConteudo(getText("predefinido.nome"));
			
			conteudo.setDeCabecalho(getText("predefinido.cabecalho"));
			conteudo.setSitio(getSitioAtual());
			if(pagina!=null && pagina.getNuPagina()!=null && !pagina.getNuPagina().equals(0L)){
				conteudo.setNuPagina(pagina.getNuPagina());
				try{
					//Gerar lista de areas do template para sugestao de nomes
					pagina = paginaDao.select(pagina.getNuPagina());
					if(pagina==null){
						usuario.addActionError("Esta p&aacute;gina com id "+pagina.getNuPagina()+" n&atilde;o existe.");
						return SUCCESS;
					}
					String template = pagina.getPadraoApresentacao().getDePadraoApresentacao();
					Pattern pat = Pattern.compile("<!-- ini conteudo\\((.*?)\\) -->");
					Matcher mat = pat.matcher(template);
					while(mat.find()){
						listaDeNomesDeArea.add(mat.group(1));
					}
				}catch(Exception e){
					logger.error(e.getMessage());
				}
			}
		}
		
		return SUCCESS;
	}

	/**
	 * Efetiva a cria��o de um conte�do
	 * @return sucesso 
	 */
	public String incluirConteudo() {
		Usuario usuario = getUsuarioLogado();
		if(usuario==null){
			return "login";
		}
		conteudo.setNuConteudo(null);
		conteudo.setNuUsuario(usuario.getNuUsuario());
		//Controle de s�tios
		conteudo.setSitio(getSitioAtual());
		conteudoDao.create(conteudo);
		carregarListas();
		usuario.addActionMessage("Conte&uacute;do inclu&iacute;do com sucesso.");
		logDao.addLog(usuario,"Conte&uacute;do adicionado. ['"+conteudo.getNoConteudo()+"', id = "+conteudo.getNuConteudo()+" ].");
		return SUCCESS;
	}

	/**
	 * Inicia o processo de editar um conte�do
	 * @return sucesso
	 */
	public String editarConteudo() {
		carregarListas();
		Usuario usuario = getUsuarioLogado();
		if(btnGravar!=null){
			//verifica se pode editar o conteudo
			if(!SecurityManager.podeAlterarConteudo(usuario, conteudo)){
				addActionError("Voc n&atilde;o pode alterar este conte&uacute;do.");
			}else{
				Conteudo conteudoDB = conteudoDao.select(conteudo.getNuConteudo());
				conteudoDB.setCoOrdemDecrescente(conteudo.isCoOrdemDecrescente());
				conteudoDB.setDeCabecalho(conteudo.getDeCabecalho());
				conteudoDB.setNoConteudo(conteudo.getNoConteudo());
				conteudoDB.setNuPagina(conteudo.getNuPagina());
				conteudoDB.setNuTipoOrdenacao(conteudo.getNuTipoOrdenacao());
				List<ItemConteudo> listItemConteudo = conteudoDao.listarItemConteudo(conteudoDB,0,1,true);
				if (listItemConteudo.size() >0){
					//verifica se esta alterando o tipo de conteudo
					if(!conteudoDB.getNuTipoConteudo().equals(conteudo.getNuTipoConteudo())){
						addActionError("Este conte&uacute;do possui itens de conte&uacute;do, por isso n&atilde;o foi poss&iacute;vel aterar o seu tipo! ");
						conteudo.setTipoConteudo(conteudoDB.getTipoConteudo());
						conteudo.setNuTipoConteudo(conteudoDB.getNuTipoConteudo());
					}
				}else{
					//nao possui itens de conteudo entao podemos alterar o seu tipo
					conteudoDB.setNuTipoConteudo(conteudo.getNuTipoConteudo());
				}
				conteudoDao.update(conteudoDB);
				usuario.addActionMessage("Conte&uacute;do alterado com sucesso.");
				logDao.addLog(usuario,"Conte&uacute;do alterado. ['"+conteudo.getNoConteudo()+"', id = "+conteudo.getNuConteudo()+" ].");
			}
		}else{
			if(conteudo!=null){
				conteudo = conteudoDao.select(conteudo.getNuConteudo());
				if(conteudo == null){
					usuario.addActionError("O conte&uacute;do solicitado n&atilde;o existe.");
					return INPUT;				
				}
			}else{
				usuario.addActionError("O conte&uacute;do solicitado n&atilde;o existe.");
				return INPUT;			
			}
		}
		return SUCCESS;
	}

	/**
	 * Lista os conte&uacute;dos cadastrados
	 */
	public String listarConteudo() {
		try {
			if (pagina == null) {	
				Usuario usuario = getUsuarioLogado();
				if (usuario.getPerfil().getNuPerfil().equals(1L) || usuario.getNuUsuario().equals(1L)) {
					logger.debug("Listando conteudo do sitioAtual " + getSitioAtual().getNuSitio());
					listConteudo = conteudoDao.getListaTodos(getSitioAtual());
				} else {
					logger.debug("Listando conteudo do setor " + usuario.getSetor().getNuSetor());
					listConteudo = conteudoDao.getListaPermitidoSetor(usuario.getSetor());//usuario.getSetor().getListConteudo();
				}
			} else {
				logger.debug("Listando conteudo da pagina " + pagina.getNuPagina());
				pagina = paginaDao.select(pagina.getNuPagina());
				listConteudo = pagina.getListConteudo();
			}
		} catch (Exception e) {
			logger.error("Erro ao listar conteudo " + pagina,e);
		}
		return SUCCESS;
	}

	public String confirmarApagarConteudo() {
		conteudo = conteudoDao.select(conteudo.getNuConteudo());
		List<ItemConteudo> listItemConteudo = conteudoDao.listarItemConteudo(conteudo, 0, 1,true);
		if (listItemConteudo.size() >0){
			addActionError("Este conte&uacute;do possui itens de conte&uacute;do, por isso n&atilde;o &eacute; poss&iacute;vel apag&aacute;-lo. Por favor remova os itens primeiro! ");
		}
		return SUCCESS;
	}

	public List<Conteudo> getListConteudo() {
		return listConteudo;
	}

	/**
	 * Apaga um conteudo
	 * @return SUCCESS
	 */
	public String apagarConteudo() {
		Usuario usuario = getUsuarioLogado();
		try {
			if (btnCancelar == null) {
				//verifica se pode editar o conteudo
				if(!SecurityManager.podeAlterarConteudo(usuario, conteudo)){
					usuario.addActionError("Voc&ecirc; n&atilde;o pode apagar este conte&uacute;do.");
				}else{
					long nu_conteudo = conteudo.getNuConteudo();
					//verifica se tem conte�do, sen�o tiver apaga, se tiver envia mensagem de erro
					conteudo=conteudoDao.select(nu_conteudo);
					List<ItemConteudo> listItemConteudo = conteudoDao.listarItemConteudo(conteudo, 0, 1,true);
					if (listItemConteudo.size() >0){
						usuario.addActionError("Este conte&uacute;do possui itens de conte&uacute;do, por isso n&atilde;o &eacute; poss&iacute;vel apag&aacute;-lo. Por favor remova os itens primeiro! ");
						return INPUT;
					} else {
						//remover o conteudo
						conteudoDao.apagar(conteudo.getNuConteudo());
						logDao.addLog(usuario,"Conte&uacute;do removido com sucesso. Id [ "+nu_conteudo+" ].");
						usuario.addActionMessage("Conte&uacute;do removido com sucesso.");
						listarConteudo();
					}
				}
			}
		} catch (Exception e) {
			usuario.addActionError("Erro: " + e.getMessage());
			logger.error("Erro ao apagar ",e);
			return INPUT;
		}
		return SUCCESS;
	}
	
	public void setListConteudo(List<Conteudo> listConteudo) {
		this.listConteudo = listConteudo;
	}

	public Conteudo getConteudo() {
		return conteudo;
	}

	public void setConteudo(Conteudo conteudo) {
		this.conteudo = conteudo;
	}

	public List<Pagina> getListPagina() {
		return listPagina;
	}

	public void setListPagina(List<Pagina> listPagina) {
		this.listPagina = listPagina;
	}

	public List<TipoConteudo> getListTipoConteudo() {
		return listTipoConteudo;
	}

	public void setListTipoConteudo(List<TipoConteudo> listTipoConteudo) {
		this.listTipoConteudo = listTipoConteudo;
	}

	public Sitio getSitio() {
		return sitio;
	}

	public void setSitio(Sitio sitio) {
		this.sitio = sitio;
	}

	public Pagina getPagina() {
		return pagina;
	}

	public void setPagina(Pagina pagina) {
		this.pagina = pagina;
	}
	
	/**
	 * Nomes para sugerir ao usuario
	 * @return lista de nomes
	 */
	public List<String> getListaDeNomesDeArea() {
		return listaDeNomesDeArea;
	}
	
	/**
	 * Nomes para sugerir ao usuario
	 * @param listaDeNomesDeArea lista de nomes
	 */
	public void setListaDeNomesDeArea(List<String> listaDeNomesDeArea) {
		this.listaDeNomesDeArea = listaDeNomesDeArea;
	}
}
